class TheFallenMight_PlayerController extends PlayerController;

 /*	 ================================================
 *   ===============   variables   ==================
 *   ================================================
 */
var float DeltaTimeAccumulated; //Accumulate time to check for mouse clicks

var bool bLeftMousePressed;     //Initialize this function in StartFire and off in StopFire
var bool bRightMousePressed;    //Initialize this function in StartFire and off in StopFire
var float CameraPanningSpeed;	//Speed of Camera movenment
var Vector CameraPanDelta;	    //Vector to aply on Position
var int PCZoffset,PCZoffsetMin,PCZoffsetMax;	        //Z offset of the PC from ground
/**
 * Tutorial variables
 */
var bool        bDrawTraces;                //Hold exec console function switch to display debug of trace lines & Paths.
var Vector2D    PlayerMouse;                //Hold calculated mouse position (this is calculated in HUD)

var Vector      MouseHitWorldLocation;      //Hold where the ray casted from the mouse in 3d coordinate intersect with world geometry. We will
//use this information for our movement target when not in pathfinding.

var Vector      MouseHitWorldNormal;        //Hold the normalized vector of world location to get direction to MouseHitWorldLocation (calculated in HUD, not used)
var Vector      MousePosWorldLocation;      //Hold deprojected mouse location in 3d world coordinates. (calculated in HUD, not used)
var Vector      MousePosWorldNormal;        //Hold deprojected mouse location normal. (calculated in HUD, used for camera ray from above)

/*****************************************************************
*  Calculated in Hud after mouse deprojection, uses MousePosWorldNormal as direction vector
*  This is what calculated MouseHitWorldLocation and MouseHitWorldNormal.
*
*  See Hud.PostRender, Mouse deprojection needs Canvas variable.
*
*  **/
var vector      StartTrace;                 //Hold calculated start of ray from camera
var Vector      EndTrace;                   //Hold calculated end of ray from camera to ground
var vector      RayDir;                     //Hold the direction for the ray query.
var Vector      PawnEyeLocation;            //Hold location of pawn eye for rays that query if an obstacle exist to destination to pathfind.
var Actor       TraceActor;                 //If an actor is found under mouse cursor when mouse moves, its going to end up here.

var MeshMouseCursor MouseCursor; //Hold the 3d mouse cursor
/**
 * Tutorial variables ends there
 */ 

/*	 ================================================
 *   ===============   Functions   ==================
 *   ================================================
 */

/**
 * StartUp of the controller. 
 * 
 * 
 * 
 *  */
simulated event PostBeginPlay()
{
	super.PostBeginPlay();
	`Log("TheFallenMight_PlayerController initelised");
	MouseCursor = Spawn(class'MeshMouseCursor', self, 'marker');
}

/**
 *  Declare a new console command to control debug of 3d line
 *  debug drawing. This will also control of showing the paths
 *  the pawn will have available into its calculated routes.
 */
exec function ToggleIsometricDebug()
{
        bDrawTraces = !bDrawTraces;
        if(bDrawTraces)
        {
                `Log("Showing debug line trace for mouse");
        }
        else
        {
                `Log("Disabling debug line trace for mouse");
        }
}

 /**
 * Moving Camera Out 
 * 
 * 
 * 
 *  */
	exec function NextMb()
		{
			`Log("MouseScrollUp");
			if (PCZoffset<PCZoffsetMax)	PCZoffset +=50.f;
			else PCZoffset = PCZoffsetMax;
		}




/**
 * Moving Camera In
 * 
 * 
 * 
 */
	exec function PrevMB()
		{
			`Log("MouseScrollDown");
			if (PCZoffset>PCZoffsetMin)	PCZoffset -=50.f;
			else PCZoffset = PCZoffsetMin;
		}





 /** 
 *  StartFire is called on mouse pressed, here to calculate a mouse click we
 *  set the timer to 0, then initialize mouseButtons according to function
 *  parameter and set the initial destination of the mouse press. Real
 *  process is in PlayerTick function.
 */
	exec function StartMB(optional byte FireModeNum)
		{
			local TheFallenMight_Camera TheFallenMight_Camera;
			local vector NewLocation, HitWorldLocation, HitWorldNormal, up, pos;
			local rotator Rot;
			local TheFallenMigth_CameraBlockingVolume TheFallenMigth_CameraBlockingVolume;
			local actor HitActor;
			TheFallenMight_Camera=TheFallenMight_Camera(PlayerCamera);
			//Set timer
			DeltaTimeAccumulated =0;

			//Set initial location of destination
//			SetDestinationPosition(MouseHitWorldLocation);

			//Initialize mouse pressed over time.
			bLeftMousePressed = FireModeNum == 0;
			bRightMousePressed = FireModeNum == 1;

			//comment these if not needed
			if(bLeftMousePressed) `Log("Left Mouse pressed");
			if(bRightMousePressed) `Log("Right Mouse pressed");
			if(bRightMousePressed && TheFallenMight_Camera.CameraType==CAM_MapView)
			{
				//calculate future position
				NewLocation = MouseHitWorldLocation;
				NewLocation.Z = -5000;
				Up = vector(TheFallenMight_Camera.CameraProperties.MapCamRotation);
				Up.Z+=2;
				ForEach TraceActors(class'TheFallenMigth_CameraBlockingVolume', TheFallenMigth_CameraBlockingVolume, HitWorldLocation, HitWorldNormal, NewLocation+up*65536.f, NewLocation) 
					{  
					break; 
					}
				HitWorldLocation.Z+=PCZoffset;
				SetLocation(HitWorldLocation);
				NewLocation = HitWorldLocation - Vector(Rotation) * TheFallenMight_Camera.CameraProperties.CamOffsetDistance;
				HitActor = Trace(HitWorldLocation, HitWorldNormal, NewLocation, HitWorldLocation, FALSE, vect(12,12,12));
				NewLocation = (HitActor == None) ? NewLocation : HitWorldLocation;
				TheFallenMight_Camera.SwitchTo(NewLocation,Rotation,CAM_Isometric);
			}
		}





/**
 *  StopFire
 *  is called on mouse release, here check the time the buttons have
 *  been pressed (this should be enhanced, but it was kept simple for the tutorial).
 *  if DeltaAccumulated < 0.1300 (medium time mouse click) then we calculate it as
 *  a mouse click, else simply stop any state running. EDIT: You must understand only
 *  a single timer has been kept for all mouse button, you should duplicate a timer
 *  for each individual mouse button if you want to support thing like auto-fire while
 *  walking in a direction.
 *
 */
exec function StopMB(optional byte FireModeNum )
	{
        `Log("delta accumulated"@DeltaTimeAccumulated);
        //Un-Initialize mouse pressed over time.
        if(bLeftMousePressed && FireModeNum == 0)
        {
                bLeftMousePressed = false;
                `Log("Left Mouse released");
        }
        if(bRightMousePressed && FireModeNum == 1)
        {
                bRightMousePressed = false;
                `Log("Right Mouse released");
        }

        //If we are not near destination and click occured
        //if(!bPawnNearDestination && DeltaTimeAccumulated < 0.13f)
        //{
        //        //Our pawn has been ordered to a single location on mouse release.
        //        //Simulate a firing bullet. If it would be ok (clear sight) then we can move to and simply ignore pathfinding.
        //        if(FastTrace(MouseHitWorldLocation, PawnEyeLocation,, true))
        //        {
        //                //Simply move to destination.
        //                MovePawnToDestination();
        //        }
        //        else
        //        {
        //                //fire up pathfinding
        //                //ExecutePathFindMove();
        //        }
        //}
        //else
        //{
        //        //Stop player from going on in that direction forever. This normally needs to be done
        //        //after a long mouse held. This will make the player stop its current MoveMousePressedAndHold
        //        //state.
        //        PopState();
        //}
        //reset accumulated timer for mouse held button
        DeltaTimeAccumulated = 0;
	}

/**
 * 	Camera to Map view.
 * 
 */
exec function CameraMapView()
{
	local TheFallenMight_Camera TheFallenMight_Camera;
    TheFallenMight_Camera = TheFallenMight_Camera(PlayerCamera);
    TheFallenMight_Camera.SwitchTo(TheFallenMight_Camera.CameraProperties.MapCamPosition,TheFallenMight_Camera.CameraProperties.MapCamRotation,CAM_MapView);
}

/**
 *  UpdateRotation of the controller.
 *  
 *  
 *  
 */

function UpdateRotation( float DeltaTime )
	{
		local Rotator   DeltaRot, ViewRotation;
		//P = FalloutSTCamera(PlayerCamera);
		ViewRotation = Rotation;
		//if (P!=none)
		//	{
		//		p.CamRot(ViewRotation);
		//	}
		if (bRightMousePressed)
			{
				 // Calculate Delta to be applied on ViewRotation
				 DeltaRot.Yaw   = PlayerInput.aTurn;
				 DeltaRot.Pitch   = PlayerInput.aLookUp;
				 ProcessViewRotation( DeltaTime, ViewRotation, DeltaRot );
				 if (ViewRotation.Pitch > 60000) ViewRotation.Pitch -= ViewRotation.Pitch - 60000;
				 SetRotation(ViewRotation);
			}  
	}




/**
 *  UpdateLocation of the controller.
 *  
 *  
 *  
 */
function UpdateLocation (float DeltaTime)
{
	local Rotator RotationYaw;
    local vector nCameraPanDelta, NewLocation, Up, HitWorldLocation, HitWorldNormal;
    Local int WIsPressed, SIsPressed, AIsPressed, DIsPressed;
    local bool bMove;
	local TheFallenMight_Camera TheFallenMight_Camera;
	local TheFallenMigth_CameraBlockingVolume TheFallenMigth_CameraBlockingVolume;
	RotationYaw.Yaw = Rotation.Yaw;
	TheFallenMight_Camera=TheFallenMight_Camera(PlayerCamera);
//	FalloutSTHUD = FalloutSTHUD(myHUD);
    WIsPressed = PlayerInput.PressedKeys.Find('W');
    SIsPressed = PlayerInput.PressedKeys.Find('S');
    AIsPressed = PlayerInput.PressedKeys.Find('A');
    DIsPressed = PlayerInput.PressedKeys.Find('D');
    nCameraPanDelta = Vect(0.f, 0.f, 0.f);
		if (TheFallenMight_Camera.CameraType!=CAM_Switcher)
		{
			if (WIsPressed >= 0 /*|| PlayerMouse.Y == 0*/)
			{		   
				if (WIsPressed > SIsPressed /*|| PlayerMouse.Y == 0*/)
				{ 
					nCameraPanDelta.X += 1.f;
					bMove = true;
				} 
			}
			if (SIsPressed >= 0 /*|| PlayerMouse.Y == FalloutSTHUD.SizeY*/)
			{
				if (SIsPressed > WIsPressed /*|| PlayerMouse.Y == FalloutSTHUD.SizeY*/)
				{
					nCameraPanDelta.X -= 1.f;			
					bMove = true;			  
				}			 
			}
			if (AIsPressed >= 0 /*|| PlayerMouse.X == 0*/) 
			{ 
				if (AIsPressed > DIsPressed /*|| PlayerMouse.X == 0*/)
				{
					nCameraPanDelta.Y -= 1.f;
					bMove = true;
				}
			}
			if (DIsPressed >= 0 /*|| PlayerMouse.X == FalloutSTHUD.SizeX*/)	
			{
				if (DIsPressed > AIsPressed /*|| PlayerMouse.X == FalloutSTHUD.SizeX*/)
				{ 
					nCameraPanDelta.Y += 1.f;
					bMove = true;
				}
			} 
			if(bMove && CameraPanningSpeed < TheFallenMight_Camera.CameraProperties.CameraMaxPanningSpeed) 
			{
				CameraPanningSpeed += TheFallenMight_Camera.CameraProperties.CameraPanningAcceleration;
			}
			if(bMove && CameraPanningSpeed >= TheFallenMight_Camera.CameraProperties.CameraMaxPanningSpeed)
			{
				CameraPanningSpeed = TheFallenMight_Camera.CameraProperties.CameraMaxPanningSpeed;
			}
			if(!bMove)
			{
				CameraPanningSpeed = 1000.f;
			}
			CameraPanDelta = Normal(nCameraPanDelta >> RotationYaw) * CameraPanningSpeed * DeltaTime;
			NewLocation = Location + CameraPanDelta;
			if(NewLocation.X > TheFallenMight_Camera.CameraProperties.WorldMaxPos.X) NewLocation.X = TheFallenMight_Camera.CameraProperties.WorldMaxPos.X;
			if(NewLocation.Y > TheFallenMight_Camera.CameraProperties.WorldMaxPos.Y) NewLocation.Y = TheFallenMight_Camera.CameraProperties.WorldMaxPos.Y;
			if(NewLocation.X < TheFallenMight_Camera.CameraProperties.WorldMinPos.X) NewLocation.X = TheFallenMight_Camera.CameraProperties.WorldMinPos.X;
			if(NewLocation.Y < TheFallenMight_Camera.CameraProperties.WorldMinPos.Y) NewLocation.Y = TheFallenMight_Camera.CameraProperties.WorldMinPos.Y;
			NewLocation.Z = -5000.f;
			Up = vector(TheFallenMight_Camera.CameraProperties.MapCamRotation);
			Up.Z+=2;
			ForEach TraceActors(class'TheFallenMigth_CameraBlockingVolume', TheFallenMigth_CameraBlockingVolume, HitWorldLocation, HitWorldNormal, NewLocation+up*65536.f, NewLocation) 
				{  
					break; 
				} 
			HitWorldLocation.Z+=PCZoffset;
			SetLocation(HitWorldLocation);
		}
}





/**
 *  PlayerTick is called each frames.
 *  
 *  
 *  
 */
	event PlayerTick( float DeltaTime )
	{
		local TheFallenMight_Camera TheFallenMight_Camera;
		TheFallenMight_Camera=TheFallenMight_Camera(PlayerCamera);
        //super.PlayerTick(DeltaTime);

        //Set the location of the 3d marker that moves with the mouse.
        MouseCursor.SetLocation(MouseHitWorldLocation); 
		UpdateLocation (DeltaTime);
		PlayerInput.PlayerInput(DeltaTime);
		AdjustFOV(DeltaTime);
        //We use the right mouse button to rotate camera.
        if(bRightMousePressed && TheFallenMight_Camera.CameraType==CAM_Isometric)
        {
			UpdateRotation(DeltaTime);
        }
		 if(bLeftMousePressed)
        {
            //accumulate the time for knowing how much time the button was pressed.
            DeltaTimeAccumulated += DeltaTime;
        }
	}



DefaultProperties
{
	InputClass=class'MouseInterfacePlayerInput';
	CameraClass=class'TheFallenMight_Camera'
	CameraPanningSpeed=1000.f
	PCZoffset=1500.f
	PCZoffsetMin=200.f
	PCZoffsetMax=2000.f
}
